/*
 * ========THE SOLMIX PROJECT=====================================
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.gnu.org/licenses/ 
 * or see the FSF site: http://www.fsf.org. 
 */
package org.solmix.web.internal;

import java.util.Dictionary;
import java.util.Hashtable;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedService;
import org.osgi.util.tracker.ServiceTracker;
import org.solmix.commons.util.DataUtil;
import org.solmix.fmk.config.ConfigRealm;
import org.solmix.fmk.config.impl.ConfigRealmImpl;
import org.solmix.fmk.config.impl.Module;
import org.solmix.fmk.config.impl.NamespaceHandler;
import org.solmix.services.datasource.DataSourceManagerService;
import org.solmix.services.interfaces.CompressionService;
import org.solmix.services.rpc.RPCManagerService;
import org.solmix.web.security.ShiroConfigIniManager;


/**
 * 
 * @author solomon
 * @version $Id$  2011-10-21
 */

public class Activator implements BundleActivator
{

    static Activator instance;
    private BundleContext bundleContext;
    private ServiceRegistration msRegistration;
    private ServiceRegistration realmRegistration;
    private String PID="org.solmix.service.cm.servlet";
    private String MODULE_NAME ="solmix-servlet";
    private ConfigRealm realm;
    private ServiceTracker rpcTracker;
    private ServiceTracker dsmTracker;
    private ServiceTracker compressionTracker;
    public static Activator getDefault(){
        return instance;
    }
    /**
     * {@inheritDoc}
     * 
     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
     */
    @Override
    public void start(BundleContext context) throws Exception {
        instance=this;
        this.bundleContext=context;
        ManagedService service = tryToCreateManagerService();
        if (service != null) {
            Dictionary<String, String> filter = new Hashtable<String, String>();
            filter.put(Constants.SERVICE_PID, PID);
            msRegistration = bundleContext.registerService(ManagedService.class.getName(), service, filter);
        }
        /************************
         * for own configuration manage.
         ***********************/
         realm = createConfigRealm();
        if (realm != null) {
            Dictionary<String, String> filter = new Hashtable<String, String>();
            filter.put(NamespaceHandler.SOLMIX_SERVICE_MODULE, MODULE_NAME);
            realmRegistration = bundleContext.registerService(ConfigRealm.class.getName(), realm, filter);
        }
        rpcTracker = new ServiceTracker(context,RPCManagerService.class.getName(),null);
        rpcTracker.open();
        dsmTracker = new ServiceTracker(context,DataSourceManagerService.class.getName(),null);
        dsmTracker.open();
        compressionTracker = new ServiceTracker(context,CompressionService.class.getName(),null);
        compressionTracker.open();
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
     */
    @Override
    public void stop(BundleContext context) throws Exception {
        if (this.msRegistration != null) {
            msRegistration.unregister();
            msRegistration = null;
        }
        if (this.realmRegistration != null) {
            realmRegistration.unregister();
            realmRegistration = null;
        }
        realm=null;
        if(rpcTracker!=null){
            rpcTracker.close();
        }
        if(dsmTracker!=null){
            dsmTracker.close();
        }
        if(compressionTracker!=null){
            compressionTracker.close();
        }

    }
    /**
     * Try to create a ManagedService.
     */
    private ManagedService tryToCreateManagerService() {
        try {
            return new ManagedService() {

                @Override
                public void updated(Dictionary properties) throws ConfigurationException {

                    createOrUpdateShiroIni(properties);
                }
            };
        } catch (Exception e) {
        }
        return null;
    }
    /**
     * @param properties
     */
    public ShiroConfigIniManager createOrUpdateShiroIni(Dictionary properties) {
        
      return null;
    }
    private ConfigRealm createConfigRealm(){
        ConfigRealm realm = new ConfigRealmImpl();
        Module module = new Module();
        module.setPersistentId(PID);
        
        realm.setModules(DataUtil.makeListIfSingle(module));
        return realm;
    }
    public ConfigRealm getCMService(){
       return realm;
    }
    public RPCManagerService getRPCMService() {
        try {
            return  (RPCManagerService)rpcTracker.waitForService(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return null;
        }
    }
    public DataSourceManagerService getDSMService() {
        try {
            return  (DataSourceManagerService)dsmTracker.waitForService(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return null;
        }
    }
    public CompressionService getCompressionService() {
        try {
            return  (CompressionService)compressionTracker.waitForService(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return null;
        }
    }
}
